package dev.ece.suit.loader.models.fbx;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class FBXAnimationCurve {

	public static final String ANIMATION_CURVE = "AnimationCurve";
	
	public static final String KEY_TIME = "KeyTime";
	
	public static final String KEY_VALUE_FLOAT = "KeyValueFloat";
	
	private FBXAnimationCurve() {}
	
	private long id;
	
	private long[] keyTime;
	
	private float[] keyValue;
	
	public static FBXAnimationCurve[] parseFBXAnimationCurve(List<FBXElement> elements) throws IOException {
		if(elements != null && !elements.isEmpty()) {
			FBXAnimationCurve[] curves = new FBXAnimationCurve[elements.size()];
			FBXElement element = null;
			FBXElement child = null;
			for(int i=0; i<curves.length; i++) {
				element = elements.get(i);
				curves[i] = new FBXAnimationCurve();
				curves[i].id = (Long) element.getProperties()[0].getValue();
				child = element.findFirstChild(KEY_TIME);
				curves[i].keyTime = child.getProperties()[0].toLongArray();
				child = element.findFirstChild(KEY_VALUE_FLOAT);
				curves[i].keyValue = child.getProperties()[0].toFloatArray();
			}
			return curves;
		}
		return null;
	}

	public static void connectToFBXAnimationCurveNode(Map<Long, List<FBXConnection>> connections, FBXAnimationCurve[] curves, FBXAnimationCurveNode[] nodes) {
		if(curves != null) {
			Map<Long, FBXAnimationCurveNode> nodemap = FBXAnimationCurveNode.toFBXAnimationCurveNodeMap(nodes);
			List<FBXConnection> conns = null;
			FBXAnimationCurveNode node = null;
			for(FBXAnimationCurve curve: curves) {
				conns = connections.get(curve.getId());
				if(conns != null) {
					for(FBXConnection conn: conns) {
						node = nodemap.get(conn.getTo());
						if(node != null) {
							node.getCurves().add(curve);
						}
					}
				}
			}
		}
	}
	
	public float interpolate(long fbx_time) {
		int count = this.keyTime.length;
		if (fbx_time < keyTime[0]) fbx_time = keyTime[0];
		if (fbx_time > keyTime[count - 1]) fbx_time = keyTime[count - 1];
		for (int i = 1; i < count; ++i) {
			if (keyTime[i] >= fbx_time) {
				float t = (float) ((double) (fbx_time - keyTime[i - 1]) / ((double)(keyTime[i] - keyTime[i - 1])));
				return keyValue[i - 1] * (1 - t) + keyValue[i] * t;
			}
		}
		return keyValue[0];
	}
	
	public long getId() {
		return id;
	}

	public long[] getKeyTime() {
		return keyTime;
	}

	public float[] getKeyValue() {
		return keyValue;
	}
	
}
